// 题目描述
// 54. 螺旋矩阵
// 提示
// 中等
// 1.5K
// 给你一个 m 行 n 列的矩阵 matrix ，请按照 顺时针螺旋顺序 ，返回矩阵中的所有元素。
//   示例 1：
// 输入：matrix = [[1,2,3],[4,5,6],[7,8,9]]
// 输出：[1,2,3,6,9,8,7,4,5]
// 示例 2：
// 输入：matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
// 输出：[1,2,3,4,8,12,11,10,9,5,6,7]
//   提示：
// m == matrix.length
// n == matrix[i].length
// 1 <= m, n <= 10
// -100 <= matrix[i][j] <= 100
// 通过次数
// 403.6K
// 提交次数
// 813.6K
// 通过率
// 49.6%
// https://leetcode.cn/problems/spiral-matrix

/**
 * 顺时针遍历矩阵
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function (matrix) {
  if (!matrix.length || !matrix[0].length) {
    return []
  }

  const order = []

  const rows = matrix.length
  const columns = matrix[0].length

  // left, right, top, bottom 是外圈的边界
  let [left, right, top, bottom] = [0, columns - 1, 0, rows - 1]
  // 这道题目，边界比较容易出错
  while (left <= right && top <= bottom) { // 这里为什么是小于等于？？因为剩余一行一列也要走完
    // 1. 走完最上面一行
    for (let column = left; column <= right; ++column) {
      order.push(matrix[top][column])
    }
    // 2. 走完最右面一列
    for (let row = top + 1; row <= bottom; ++row) {
      order.push(matrix[row][right])
    }
    // 这里为什么加了个判断？？
    // 因为上面走完了一行一列，有可能没有格子了，防止越界
    // 为什么这里的判断是小于而不是小于等于？？
    // 因为，上面走完了一行一列，只有严格小于才能保证这里还剩下一行一列可以走
    if (left < right && top < bottom) {
      // 3. 走完最下面一行（从右往左）
      for (let column = right - 1; column > left; --column) {
        order.push(matrix[bottom][column])
      }
      // 4. 走完最左面一列（从下往上）
      for (let row = bottom; row > top; --row) {
        order.push(matrix[row][left])
      }
    }

    // 更新外圈的边界
    [left, right, top, bottom] = [left + 1, right - 1, top + 1, bottom - 1]
  }

  return order
}
console.log(
  spiralOrder(
    [[1,2,3],[4,5,6],[7,8,9]]
  )
)
